#include <stdio.h>
#include <stdint.h>
typedef union {
    uint64_t a;
    double   b;
    struct {
        uint64_t p1 : 1;
        uint64_t p2 : 11;
        uint64_t p3 : 52;
    } s;
} u_t;

void printf_ut(u_t tmp, int type)
{
    printf("uint64: 0x%lx\n", tmp.a);
    printf("double: %lf\n", tmp.b);
    printf("part 1: 0x%lx\n", tmp.s.p1);
    printf("part 2: 0x%lx\n", tmp.s.p2);
    printf("part 3: 0x%lx\n", tmp.s.p3);
    printf("\n");
}

int main()
{
    printf("sizeof  float: %lu\n", sizeof(float));
    printf("sizeof double: %lu\n", sizeof(double));
    u_t tmp;
    tmp.a = 0x1010010002000304ul;
    printf_ut(tmp, 0);
    tmp.a = 0x220010040050010ul;
    printf_ut(tmp, 0);
    tmp.a = 0x403374bc6a7ef9db;
    printf_ut(tmp, 0);
    tmp.a = 0x4037742c3c9eecc0;
    printf_ut(tmp, 0);
    tmp.a = 0x407c8512f9d7c7d3;
    printf_ut(tmp, 0);
    return 0;
}

/* 
double长度64位，这64位的含义是这样的：
符号位S(最高位的第63位，含义和整数的符号位相同)
阶码位E（从第52-62位的11位）
有效数字位M（从第0位-51位的52位，并且还有一位最高隐含位，实际上是53位)
M可以看作是一个二进制小数，只有一位整数（就是隐含位），其他的都是小数，也就是m=1.xxxxxxxxxx....或者0.xxxxxxxxxx.....

符号位没什么说的
指数的值是代表有效数字M的小数点向左或者向右移动的次数的
解释一下阶码：
阶码全为1时，代表整个double溢出,
阶码全为0时 代表指数为：-1022，并且M的最高隐含位为0；
阶码不全为0或着1,那么指数等于阶码减去1023,并且M的最高隐含位为1；


举个例子说明：
double格式的1234.5在内存中存储如下：
01000000 10010011 01001010 00000000 00000000 00000000 00000000 00000000 
符号位为0，说明是个正数
阶码为 10000001001 换算成10进制是1033,1033-1023=10,指数为10
因为阶码不全为0或者1,所以隐含位为1，有效数字为:
1.0011 01001010 00000000 00000000 00000000 00000000 00000000 
指数为10，小数点向右移动10次：
10011 010010.10 00000000 00000000 00000000 00000000 00000000
10011010010.1 换算为10进制就是1234.5
*/
